package com.viewlibrary;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.Nullable;
import android.text.InputType;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.inputmethod.BaseInputConnection;
import android.view.inputmethod.CorrectionInfo;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;

import java.util.ArrayList;
import java.util.List;

public class PswText extends View {
    private int pswLength;
    private int delayTime;
    private int borderDefaultColor;
    private int borderInputColor;
    private int pswTextColor;
    private int pswTextSize;

    private int borderRadius;

    private int borderWidth;
    private int spacingWidth;

    private Paint mClearTextPaint;
    private Paint mDarkTextPaint;
    private Paint mBorderDefaultPaint;
    private Paint mBorderInputPaint;

    private int height;//view高度
    private final RectF borderRectF;
    private InputMethodManager inputMethodManager;
    private List<Integer> inputResult = new ArrayList<>();
    private int inputTotal;//记录已输入密码数
    private boolean isInvalidate = false;
    Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case 1:
                    isInvalidate = true;
                    invalidate();
                    break;
            }
        }
    };

    public PswText(Context context) {
        this(context, null);
    }

    public PswText(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public PswText(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        setFocusable(true);
        setFocusableInTouchMode(true);
        setOnKeyListener(new NumberKeyListener());
        inputMethodManager = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);

        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.PswText);
        pswLength = typedArray.getInteger(R.styleable.PswText_pswLength, 6);
        delayTime = typedArray.getInteger(R.styleable.PswText_delayTime, 1000);
        borderDefaultColor = typedArray.getColor(R.styleable.PswText_borderDefaultColor, Color.parseColor("#999999"));
        borderInputColor = typedArray.getColor(R.styleable.PswText_borderInputColor, Color.parseColor("#3779e3"));
        pswTextColor = typedArray.getColor(R.styleable.PswText_pswTextColor, Color.parseColor("#3779e3"));
        pswTextSize = (int) typedArray.getDimension(R.styleable.PswText_pswTextSize, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 18, getResources().getDisplayMetrics()));
        borderRadius = (int) typedArray.getDimension(R.styleable.PswText_borderRadius, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 5, getResources().getDisplayMetrics()));
        typedArray.recycle();

        borderWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 40, getResources().getDisplayMetrics());
        spacingWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, getResources().getDisplayMetrics());

        borderRectF = new RectF();

        initPaint();
    }

    private void initPaint() {
        mClearTextPaint = new Paint();
        mClearTextPaint.setAntiAlias(true);
        mClearTextPaint.setColor(pswTextColor);
        mClearTextPaint.setFakeBoldText(true);//true粗体

        mDarkTextPaint = new Paint();
        mDarkTextPaint.setAntiAlias(true);
        mDarkTextPaint.setStyle(Paint.Style.FILL);
        mDarkTextPaint.setStrokeWidth(3);
        mDarkTextPaint.setColor(pswTextColor);

        mBorderDefaultPaint = new Paint();
        mBorderDefaultPaint.setAntiAlias(true);
        mBorderDefaultPaint.setStyle(Paint.Style.STROKE);
        mBorderDefaultPaint.setStrokeWidth(3);
        mBorderDefaultPaint.setColor(borderDefaultColor);

        mBorderInputPaint = new Paint();
        mBorderInputPaint.setAntiAlias(true);
        mBorderInputPaint.setStyle(Paint.Style.STROKE);
        mBorderInputPaint.setStrokeWidth(3);
        mBorderInputPaint.setColor(borderInputColor);

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);

        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        int heigthMode = MeasureSpec.getMode(heightMeasureSpec);

        switch (widthMode) {
            case MeasureSpec.AT_MOST:
                if (heigthMode == MeasureSpec.AT_MOST) {
                    //宽高均未知
                    heightSize = borderWidth;
                    widthSize = pswLength * borderWidth + (pswLength - 1) * spacingWidth;
                } else {
                    //高度已知，宽度未知,计算宽度
                    borderWidth = heightSize;
                    spacingWidth = borderWidth / 4;
                    widthSize = borderWidth * pswLength + spacingWidth * (pswLength - 1);
                }
                break;
            case MeasureSpec.EXACTLY:
                if (heigthMode == MeasureSpec.AT_MOST) {
                    //宽度已知，高度未知,求高  borderWidth=pswLength*height+(pswLengh-1)*heigth/4=(5*pswLength-1)/4*height  =>  borderWidth=width*(4/(5*pswLength-1))
                    borderWidth = widthSize * 4 / (5 * pswLength - 1);
                    spacingWidth = borderWidth / 4;
                    heightSize = (int) (borderWidth + mBorderDefaultPaint.getStrokeWidth() * 2);
                }
                break;
        }
        height = heightSize;
        setMeasuredDimension(widthSize, heightSize);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //绘制初始边框
        drawBorder(canvas);
        //输入时绘制
        if (pswTextSize == TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 18, getResources().getDisplayMetrics())) {
            pswTextSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, borderWidth / 8, getResources().getDisplayMetrics());
        }
        mClearTextPaint.setTextSize(pswTextSize);

        if (isInvalidate){
            //绘制暗文，即小圆
            for (int j = 0; j < inputResult.size(); j++) {
                drawDarkText(canvas, j);
                //绘制输入时边框
                drawInputBorder(canvas, j);
            }
            isInvalidate=false;
            handler.removeMessages(1);
            return;
        }
        for (int i = 0; i < inputResult.size(); i++) {
            //绘制明文
            String num = inputResult.get(i) + "";//输入的密码
            mClearTextPaint.getTextBounds(num, 0, num.length(), new Rect());
            Paint.FontMetrics fontMetrics = mClearTextPaint.getFontMetrics();
            float x = (borderWidth + spacingWidth) * i + borderWidth / 2;
            float y = height / 2 + (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.bottom;

            drawInputBorder(canvas,i);

            if (i+1==inputResult.size()){
                if (inputTotal!=0&&inputTotal<=inputResult.size()){
                    canvas.drawText(num, x, y, mClearTextPaint);
                }
                handler.sendEmptyMessageDelayed(1, delayTime);
            }
            //按删除键只绘制暗文
            if (inputTotal>inputResult.size()){
                drawDarkText(canvas,i);
            }

            if (i+1<inputResult.size()){
                drawDarkText(canvas,i);
            }

        }
    }

    private void drawDarkText(Canvas canvas, int j) {
        float cx = (borderWidth + spacingWidth) * j + borderWidth / 2;
        float cy = height / 2;

        canvas.drawCircle(cx, cy, borderWidth / 6, mDarkTextPaint);
    }

    private void drawInputBorder(Canvas canvas, int j) {
        float left = j * (borderWidth + spacingWidth);
        float right = (j + 1) * borderWidth + j * spacingWidth;
        borderRectF.set(left, 0, right, height);
        canvas.drawRoundRect(borderRectF, borderRadius, borderRadius, mBorderInputPaint);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            Log.d("asd", "down----");
            requestFocus();
            inputMethodManager.showSoftInput(this, InputMethodManager.SHOW_FORCED);
            return true;
        }
        return super.onTouchEvent(event);
    }

    /**
     * 绘制默认边框
     *
     * @param canvas
     */
    private void drawBorder(Canvas canvas) {
        for (int i = 0; i < pswLength; i++) {
            float left = i * (borderWidth + spacingWidth);
            float right = (i + 1) * borderWidth + i * spacingWidth;
            borderRectF.set(left, 0, right, height);
            canvas.drawRoundRect(borderRectF, borderRadius, borderRadius, mBorderDefaultPaint);

        }

    }

    class NumberKeyListener implements OnKeyListener {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            if (event.getAction() == KeyEvent.ACTION_DOWN) {
                if (event.isShiftPressed()) return false;
                if (keyCode >= KeyEvent.KEYCODE_0 && keyCode <= KeyEvent.KEYCODE_9) {
                    //0-9数字
                    if (inputResult.size() < pswLength) {
                        inputResult.add(keyCode - 7);
                        inputTotal = inputResult.size();
                        invalidate();
                        finishInput();
                    }
                    return true;
                }

                if (keyCode == KeyEvent.KEYCODE_DEL) {
                    //删除
                    if (inputResult != null && inputResult.size() > 0) {
                        inputTotal = inputResult.size();
                        inputResult.remove(inputResult.size() - 1);
                        invalidate();
                        return true;
                    }
                }
            }
            return false;
        }
    }

    @Override
    public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
            outAttrs.inputType= InputType.TYPE_CLASS_NUMBER;
            outAttrs.imeOptions=EditorInfo.IME_ACTION_DONE;
       return new NumberConnecttion(this,false);
    }
    class NumberConnecttion extends BaseInputConnection{

        public NumberConnecttion(View targetView, boolean fullEditor) {
            super(targetView, fullEditor);
        }

        @Override
        public boolean commitText(CharSequence text, int newCursorPosition) {
            return super.commitText(text, newCursorPosition);
        }

        @Override
        public boolean deleteSurroundingText(int beforeLength, int afterLength) {
            //屏蔽返回键，发送自己的删除事件
            if (beforeLength == 1 && afterLength == 0) {
                return super.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL))
                        && super.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DEL));
            }
            return super.deleteSurroundingText(beforeLength, afterLength);
        }
    }
    /**
     * 输入完成隐藏键盘
     */
    private void finishInput() {
        if (pswLength==inputResult.size()){
            InputMethodManager inputMethodManager= (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
            inputMethodManager.hideSoftInputFromWindow(getWindowToken(),0);
        }
    }

    public String getPsw(){
        StringBuilder builder=new StringBuilder();
        for (int i = 0; i < inputResult.size(); i++) {
            builder.append(inputResult.get(i));
        }
        return builder.toString();
    }
}
